package cn.zzuisa.deutsch.log;

import cn.zzuisa.deutsch.entity.Member;
import cn.zzuisa.deutsch.log.annotation.BussinessLog;
import cn.zzuisa.deutsch.log.factory.LogTaskFactory;
import cn.zzuisa.deutsch.log.sub.LogManager;
import cn.zzuisa.deutsch.utils.Context;
import cn.zzuisa.deutsch.utils.IpUtil;
import cn.zzuisa.deutsch.utils.MemberSessionKeyMap;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Enumeration;

/**
 * 日志记录
 *
 * @author fengshuonan
 * @date 2016年12月6日 下午8:48:30
 */
@Aspect
@Component
public class LogAop {

    private Logger log = LoggerFactory.getLogger(this.getClass());

    @Pointcut(value = "@annotation(cn.zzuisa.deutsch.log.annotation.BussinessLog)")
    public void cutService() {
    }

    /**
     * ProceedingJoinPoint is only supported for around advice
     *
     * @param point
     * @return
     * @throws Throwable
     */
    @Around("cutService()")
    public Object recordSysLog(ProceedingJoinPoint point) throws Throwable {

        //先执行业务
        Object result = point.proceed();

        try {
            handle(point);
        } catch (Exception e) {
            log.error("日志记录出错!", e);
        }

        return result;
    }

    private void handle(ProceedingJoinPoint point) throws Exception {

        HttpServletRequest request = Context.getRequest();
        String ip = IpUtil.getClientIp(request);

        String url = request.getRequestURL().toString();
//        Enumeration er = request.getHeaderNames();//获取请求头的所有name值
//        while(er.hasMoreElements()){
//            String name	=(String) er.nextElement();
//            String value = request.getHeader(name);
//            System.out.println("-=-=-=-"+name+"="+value);
//        }

        HttpSession session = request.getSession();

        Member member = new Member();
        MemberSessionKeyMap.USER_SESSION_KEYS.get("");
        Long userid = null;
        String userName = "游客";

        try {
            member = (Member) session.getAttribute("member");
            userid = member.getId();
            userName = member.getName();
        } catch (Exception e) {
            System.out.println("未登录，标记为游客");
        }
        Enumeration<String> hn = request.getHeaderNames();
        while (hn.hasMoreElements()) {
            String string = (String) hn.nextElement();
            System.out.println(string + ": " + request.getHeader(string));
        }
        userid = userid == null ? -1 : userid;
        //获取拦截的方法名
        Signature sig = point.getSignature();
        MethodSignature msig = null;
        if (!(sig instanceof MethodSignature)) {
            throw new IllegalArgumentException("该注解只能用于方法");
        }
        msig = (MethodSignature) sig;
        Object target = point.getTarget();
        Method currentMethod = target.getClass().getMethod(msig.getName(), msig.getParameterTypes());
        String methodName = currentMethod.getName();
//        //如果当前用户未登录，不做日志
//        Long userId = Long.parseLong(SecurityUtils.getSubject().getPrincipal().toString());
//        userId = 1L;
//        if (null == userId) {
//            return;
//        }
        //获取拦截方法的参数
        String className = point.getTarget().getClass().getName();
        Object[] params = point.getArgs();

        String method = point.getSignature().getName();
        //获取操作名称
        BussinessLog annotation = currentMethod.getAnnotation(BussinessLog.class);
        String bussinessName = annotation.value();
        String key = annotation.key();
//        Class dictClass = annotation.dict();

        StringBuilder sb = new StringBuilder();
        for (Object param : params) {
            sb.append(param);
            sb.append(" & ");
        }
        Object[] args = point.getArgs();
        String uri = request.getRequestURI();
        //如果涉及到修改,比对变化
        String msg = bussinessName;
        for (Object str : args
        ) {
            System.out.println("start:" + str.toString() + " ");

        }
        if (method.equals("getVerb")) {
            String p = (String) args[0];
            msg += p;
        } else if (method.equals("getVideo")) {
            String p = (String) args[1];
            msg += p;
            if (!args[2].equals("undefined")) {
                msg = "观看分享德语听力：#" + p;
            }
        } else if (method.equals("article")) {

            String p = (String) args[1];
            msg += p;
            if (!args[2].equals("undefined") && args[2].equals("ex")) {
                msg = "做题：#" + p;
            }
            if (!args[2].equals("undefined") && args[2].equals("share")) {
                msg = "查看分享文章：#" + p;
            }
            if (!args[2].equals("undefined") &&!args[3].equals("undefined")) {
                msg = "查看分享练习：#" + p;
            }
        }
        /*if (bussinessName.indexOf("修改") != -1 || bussinessName.indexOf("编辑") != -1) {
            Object obj1 = LogObjectHolder.me().get();
            Map<String, String> obj2 = HttpKit.getRequestParameters();
            msg = Contrast.contrastObj(dictClass, key, obj1, obj2);
        } else {
            Map<String, String> parameters = HttpKit.getRequestParameters();
            AbstractDictMap dictMap = (AbstractDictMap) dictClass.newInstance();
            msg = Contrast.parseMutiKey(dictMap,key,parameters);
        }*/

        LogManager.me().executeLog(LogTaskFactory.bussinessLog(userid, userName, ip, url, uri, bussinessName, className, methodName, msg));
    }
}
